package com.pai4j.message.sender;

import com.pai4j.message.config.EmailProperties;
import com.pai4j.message.core.sender.AbstractMessageSender;
import com.pai4j.message.factory.MessageSenderFactory;
import com.pai4j.message.model.MessageContext;
import com.pai4j.message.model.SendResult;
import jakarta.annotation.PostConstruct;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

/**
 * Email消息发送器
 * 支持HTML和纯文本格式，支持异步发送
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "pai4j.message.email", name = "enabled", havingValue = "true")
public class EmailMessageSender extends AbstractMessageSender {

    private final JavaMailSender mailSender;
    private final EmailProperties emailProperties;

    @Override
    public String getChannel() {
        return "email";
    }

    @PostConstruct
    public void register() {
        MessageSenderFactory.register(this);
        log.info("EmailMessageSender 注册成功: from={}, host={}", 
                emailProperties.getFrom(), emailProperties.getHost());
    }

    @Override
    protected SendResult doSend(MessageContext context) {
        try {
            // 验证上下文
            if (!validateContext(context)) {
                return SendResult.failure("INVALID_CONTEXT", "消息上下文验证失败", getChannel());
            }

            // 获取收件人邮箱（从扩展数据中获取，或使用receiverId作为邮箱）
            String toEmail = getRecipientEmail(context);
            if (toEmail == null || toEmail.trim().isEmpty()) {
                return SendResult.failure("NO_EMAIL", "未找到收件人邮箱地址", getChannel());
            }

            // 获取邮件标题和内容
            String subject = getEmailSubject(context);
            String content = getEmailContent(context);

            // 创建邮件消息
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, emailProperties.getEncoding());

            // 设置发件人
            String fromAddress = emailProperties.getFrom();
            String fromName = emailProperties.getFromName();
            helper.setFrom(fromAddress, fromName);

            // 设置收件人
            helper.setTo(toEmail);

            // 设置主题
            helper.setSubject(subject);

            // 设置内容（支持HTML）
            boolean isHtml = emailProperties.isHtmlEnabled();
            helper.setText(content, isHtml);

            // 处理抄送
            String cc = (String) context.getMetadata().get("cc");
            if (cc != null && !cc.trim().isEmpty()) {
                helper.setCc(cc.split(","));
            }

            // 处理密送
            String bcc = (String) context.getMetadata().get("bcc");
            if (bcc != null && !bcc.trim().isEmpty()) {
                helper.setBcc(bcc.split(","));
            }

            // 发送邮件
            mailSender.send(message);

            String messageId = generateMessageId();
            log.info("邮件发送成功: messageId={}, to={}, subject={}", messageId, toEmail, subject);

            return SendResult.success("")
                    .addExtData("to", toEmail)
                    .addExtData("subject", subject);

        } catch (MessagingException e) {
            log.error("邮件格式错误: {}", e.getMessage(), e);
            return SendResult.failure("MESSAGING_ERROR", "邮件格式错误: " + e.getMessage(), getChannel());
        } catch (MailException e) {
            log.error("邮件发送失败: {}", e.getMessage(), e);
            return SendResult.failure("MAIL_SEND_ERROR", "邮件发送失败: " + e.getMessage(), getChannel());
        } catch (Exception e) {
            log.error("邮件发送异常: {}", e.getMessage(), e);
            return SendResult.failure("UNKNOWN_ERROR", "邮件发送异常: " + e.getMessage(), getChannel());
        }
    }

    /**
     * 获取收件人邮箱
     */
    private String getRecipientEmail(MessageContext context) {
        // 优先从扩展数据中获取
        Object emailObj = context.getMetadata().get("email");
        if (emailObj != null) {
            return emailObj.toString();
        }

        // 否则使用receiverId（假设就是邮箱）
        String receiverId = context.getReceiverId();
        if (receiverId != null && receiverId.contains("@")) {
            return receiverId;
        }

        // TODO: 可以从用户服务查询用户邮箱
        log.warn("无法获取收件人邮箱: receiverId={}", receiverId);
        return null;
    }

    /**
     * 获取邮件主题
     */
    private String getEmailSubject(MessageContext context) {
        // 优先从扩展数据中获取
        Object subjectObj = context.getMetadata().get("emailSubject");
        if (subjectObj != null) {
            return subjectObj.toString();
        }

        // 根据消息类型生成默认主题
        String messageType = context.getMessageDTO() != null ? 
                context.getMessageDTO().getClass().getSimpleName() : "Message";
        return "[PAI4J] " + messageType.replace("MessageDTO", "") + " 通知";
    }

    /**
     * 获取邮件内容
     */
    private String getEmailContent(MessageContext context) {
        // 优先从扩展数据中获取
        Object contentObj = context.getMetadata().get("emailContent");
        if (contentObj != null) {
            return contentObj.toString();
        }

        // 使用消息内容
        if (context.getContent() != null && !context.getContent().trim().isEmpty()) {
            if (emailProperties.isHtmlEnabled()) {
                return buildHtmlContent(context);
            } else {
                return context.getContent();
            }
        }

        return "您收到一条新消息";
    }

    /**
     * 构建HTML格式的邮件内容
     */
    private String buildHtmlContent(MessageContext context) {
        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html>");
        html.append("<html>");
        html.append("<head>");
        html.append("<meta charset=\"UTF-8\">");
        html.append("<style>");
        html.append("body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }");
        html.append(".container { max-width: 600px; margin: 0 auto; padding: 20px; }");
        html.append(".header { background: #4CAF50; color: white; padding: 20px; text-align: center; }");
        html.append(".content { background: #f9f9f9; padding: 20px; margin-top: 20px; }");
        html.append(".footer { text-align: center; margin-top: 20px; color: #666; font-size: 12px; }");
        html.append("</style>");
        html.append("</head>");
        html.append("<body>");
        html.append("<div class=\"container\">");
        html.append("<div class=\"header\">");
        html.append("<h2>PAI4J 消息通知</h2>");
        html.append("</div>");
        html.append("<div class=\"content\">");
        html.append("<p>").append(context.getContent()).append("</p>");
        
        // 添加资源信息（如果有）
        if (context.getResourceInfo() != null) {
            html.append("<hr>");
            html.append("<p><strong>相关资源：</strong>");
            html.append(context.getResourceInfo().getTitle()).append("</p>");
            if (context.getResourceInfo().getJumpUrl() != null) {
                html.append("<p><a href=\"").append(context.getResourceInfo().getJumpUrl())
                    .append("\">查看详情</a></p>");
            }
        }
        
        html.append("</div>");
        html.append("<div class=\"footer\">");
        html.append("<p>此邮件由 PAI4J 系统自动发送，请勿回复</p>");
        html.append("</div>");
        html.append("</div>");
        html.append("</body>");
        html.append("</html>");
        
        return html.toString();
    }

    @Override
    protected boolean isRetryable(SendResult result) {
        if (result == null || result.isSuccess()) {
            return false;
        }

        // Email发送失败通常可以重试
        String code = result.getCode();
        return "MAIL_SEND_ERROR".equals(code) || 
               "MESSAGING_ERROR".equals(code) ||
               super.isRetryable(result);
    }
}

